#!/bin/bash

log_message() {
    local slot_num=$(($1+1))
    local MESSAGE="SLOT$slot_num $2 Power Fault"
    local COMBINED_INFO="$3"

    busctl call \
        xyz.openbmc_project.Logging /xyz/openbmc_project/logging \
        xyz.openbmc_project.Logging.Create Create "ssa{ss}" "$MESSAGE" \
        "xyz.openbmc_project.Logging.Entry.Level.Error" 1 "FAULT" "$COMBINED_INFO"
}



# if $1 == 14, slot1 to slot4. Check mux0 at i2c-8 0x70.
# if $1 == 58, slot5 to slot8. Check mux1 at i2c-9 0x71.

if [ "$1" -eq 14 ]; then
    i2c_bus=8
    mux_addr=0x70
    slot_num_offset=0
elif [ "$1" -eq 58 ]; then
    i2c_bus=9
    mux_addr=0x71
    slot_num_offset=4
else
    echo "Invalid input. Please provide 14 or 58."
    exit 1
fi


# i2ctranster to check which slot got interrupt
read -r INT_BYTE <<< "$(i2ctransfer -f -y $i2c_bus w1@$mux_addr 0 r1)"
INT_BYTE=$((INT_BYTE >> 4))

# Traverse INT_BYTE
count=0
SLOT_RANGE=4
while [ $count -lt $SLOT_RANGE ]
do
    fault=$(( (INT_BYTE >> count) & 1 ))
    # if fault[i] == 1, means slot_x got ISR
    if [ $fault -eq 1 ]; then
        slot_num=$((count + slot_num_offset))

        # i2ctranster to get CPLD IOE (0x24) addr 0x01 (port1, ac)
        read -r FAULT_BYTE <<< "$(i2ctransfer -f -y $slot_num w1@0x24 0x01 r1)"

        # check which pin fault, add to fault info
        if (( (FAULT_BYTE >> 0) & 1 == 1 )); then
            [ -n "$COMBINED_INFO" ] && COMBINED_INFO="${COMBINED_INFO},PWRGD_P1V8_STBY_FAULT" || COMBINED_INFO="PWRGD_P1V8_STBY_FAULT"
        elif (( (FAULT_BYTE >> 1) & 1 == 1 )); then
            [ -n "$COMBINED_INFO" ] && COMBINED_INFO="${COMBINED_INFO},PWRGD_P1V2_STBY_FAULT" || COMBINED_INFO="PWRGD_P1V2_STBY_FAULT"
        fi

        # call logging function
        if [ -n "$COMBINED_INFO" ]; then
            log_message $slot_num "AC" "$COMBINED_INFO"
        fi

        # clean
        COMBINED_INFO=""
        # i2ctranster to get CPLD IOE (0x24) addr 0x02 (port2, dc)
        read -r FAULT_BYTE <<< "$(i2ctransfer -f -y $slot_num w1@0x24 0x02 r1)"

        # check which pin fault, add to fault info
        if (( (FAULT_BYTE >> 0) & 1 == 1 )); then
            [ -n "$COMBINED_INFO" ] && COMBINED_INFO="${COMBINED_INFO},PWRGD_PVDDCR_CPU0_FAULT" || COMBINED_INFO="PWRGD_PVDDCR_CPU0_FAULT"
        elif (( (FAULT_BYTE >> 1) & 1 == 1 )); then
            [ -n "$COMBINED_INFO" ] && COMBINED_INFO="${COMBINED_INFO},PWRGD_PVDDCR_SOC_FAULT" || COMBINED_INFO="PWRGD_PVDDCR_SOC_FAULT"
        elif (( (FAULT_BYTE >> 2) & 1 == 1 )); then
            [ -n "$COMBINED_INFO" ] && COMBINED_INFO="${COMBINED_INFO},PWRGD_PVDDCR_CPU1_FAULT" || COMBINED_INFO="PWRGD_PVDDCR_CPU1_FAULT"
        elif (( (FAULT_BYTE >> 3) & 1 == 1 )); then
            [ -n "$COMBINED_INFO" ] && COMBINED_INFO="${COMBINED_INFO},PWRGD_PVDDIO_FAULT" || COMBINED_INFO="PWRGD_PVDDIO_FAULT"
        elif (( (FAULT_BYTE >> 4) & 1 == 1 )); then
            [ -n "$COMBINED_INFO" ] && COMBINED_INFO="${COMBINED_INFO},PWRGD_PVDD11_S3_R_FAULT" || COMBINED_INFO="PWRGD_PVDD11_S3_R_FAULT"
        fi

        # call logging function
        if [ -n "$COMBINED_INFO" ]; then
            log_message $slot_num "DC" $COMBINED_INFO
        fi
    fi

    count=$((count + 1))
done
